﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NDF.Collections
{
    /// <summary>
    /// 为 <see cref="System.Collections.IEqualityComparer"/> 接口的实现提供基类。
    /// 定义方法以支持对象的相等比较。
    /// </summary>
    [Serializable]
    public class EqualityComparer : IEqualityComparer
    {
        private Func<object, object, bool> comparer;
        private Func<object, int> hashCodeGetter;

        public EqualityComparer()
        {
            this.comparer = DefaultComparer;
            this.hashCodeGetter = DefaultHashCodeGetter;
        }

        public EqualityComparer(Func<object, object, bool> comparer)
        {
            this.Comparer = comparer;
        }

        public EqualityComparer(Func<object, int> hashCodeGetter)
        {
            this.HashCodeGetter = hashCodeGetter;
        }

        public EqualityComparer(Func<object, object, bool> comparer, Func<object, int> hashCodeGetter)
            : this(comparer)
        {
            this.HashCodeGetter = hashCodeGetter;
        }


        public new bool Equals(object x, object y)
        {
            return this.Comparer(x, y);
        }

        public int GetHashCode(object obj)
        {
            return this.HashCodeGetter(obj);
        }


        public Func<object, object, bool> Comparer
        {
            get
            {
                return this.comparer == null ? DefaultComparer : this.comparer;
            }
            set { this.comparer = value; }
        }

        public Func<object, int> HashCodeGetter
        {
            get
            {
                return this.hashCodeGetter == null ? DefaultHashCodeGetter : this.hashCodeGetter;
            }
            set { this.hashCodeGetter = value; }
        }




        private static EqualityComparer _default;

        public static EqualityComparer Default
        {
            get
            {
                if (_default == null)
                {
                    _default = new EqualityComparer();
                }
                return _default;
            }
        }



        public static IEqualityComparer Create(Func<object, object, bool> comparer)
        {
            return new EqualityComparer(comparer);
        }

        public static IEqualityComparer Create(Func<object, int> hashCodeGetter)
        {
            return new EqualityComparer(hashCodeGetter);
        }

        public static IEqualityComparer Create(Func<object, object, bool> comparer, Func<object, int> hashCodeGetter)
        {
            return new EqualityComparer(comparer, hashCodeGetter);
        }



        public static Func<object, object, bool> DefaultComparer = (a, b) => EqualityComparer<object>.Default.Equals(a, b);

        public static Func<object, int> DefaultHashCodeGetter = a => EqualityComparer<object>.Default.GetHashCode(a);
    }
}
